package com.cskaoyan.javase.oop3._2inner._6lambda._2notice;

/**
 * 注意事项:
 *      1.Lambda表达式是特殊的局部内部类，所以它访问方法的局部变量
 *          该变量必须是final的（实际常量）。
 *      2. 除此之外，局部内部类，匿名内部类它们都有自己独立的作用域，能够自定义自己的成员。
 *      但是Lambda表达式没有自身独立的作用域，不能自定义成员，和方法共用同一个作用域。
 *      注:如果想要知道原因,可以去看一看"闭包和回调"
 *
 *      3.Lambda表达式的实现,可以用"方法引用"指向一个已经存在的方法
 *          这个方法可以由程序员自定义
 *          当然也可以来自于JDK源码,三方工具类库中等.
 *
 *
 * @since 16:26
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        int num = 10;
        // int num2 = 10;
        IA ia = a -> true;
        System.out.println(ia.test(100));
        IA ia2 = a -> {
            // Lambda表达式的重写方法体没有自身独立的作用域,和定义Lambda表达式的局部位置共用同一个作用域
            int num2 = 100;
            // Variable 'num' is already defined in the scope
            // int num = 1000;
            // System.out.println(num);
            // 在Lambda表达式中访问作用域内部的局部变量,该局部变量是常量
            // num++;
            return false;
        };

        new IA() {
            // int num = 100;
            // 匿名子类的类体,有自身独立的作用域
            @Override
            public boolean test(int a) {
                int num = 100;
                return false;
            }
        };
        int num2 = 1000;

        System.out.println("------------------------------------");
        System.out.println("hello world!");

        // 不省略"->"的形式
        IB ib = str -> System.out.println(str);
        ib.println("6666!");

        // 省略"->"的形式
        IB ib2 = System.out::println;
        ib2.println("77777!");

        IC ic = Math::pow;
        System.out.println(ic.test(2, 10));

    }
}

@FunctionalInterface
interface IC {
    double test(double num1, double num2);
}

@FunctionalInterface
interface IB {
    void println(String str);
}

@FunctionalInterface
interface IA {
    boolean test(int a);
}
